home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir24
/
psi110g.zip
/
GLOB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-17
|
6KB
|
201 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <time.h>
#include <sys/stat.h>
#define GLOB_INTERNAL
#include "dirutil.h"
/*
* Second approximation of glob routine for JNOS/Linux
*/
static int ff1(char *, char *, char *, struct ffblk *, int);
static char *
__ff_cat(char *pfx, char *sfx)
{
static char buf[1024];
buf[0] = '\0';
if (pfx && *pfx)
strcat(buf, pfx);
if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
strcat(buf, "/");
if (sfx && *sfx)
strcat(buf, sfx);
return buf;
}
int
findnext(struct ffblk *ff)
{
struct stat sb;
char *path;
int rc, m;
/* special-case literal: if there's no pattern, just close the ff */
if (!ff->ff_pat)
return -1;
for (;;)
{
while ((ff->ff_cur = readdir(ff->ff_dir)) &&
!wildmat(ff->ff_cur->d_name, ff->ff_pat, 0))
;
if (!ff->ff_cur)
{
closedir(ff->ff_dir);
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
return -1;
}
path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
stat(path, &sb) == -1 ||
(!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
(!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
!(ff->ff_sattr & FA_HIDDEN)))
{
j_free(path);
continue;
}
j_free(path);
if (geteuid() == sb.st_uid)
m = 0700;
else if (getegid() == sb.st_gid)
m = 0070;
else
m = 0007;
if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
continue;
ff->ff_ftime = *localtime(&sb.st_mtime);
ff->ff_fsize = sb.st_size;
if (S_ISDIR(sb.st_mode))
ff->ff_attrib = FA_DIREC;
else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
else
ff->ff_attrib = FA_NORMAL;
if (*ff->ff_cur->d_name == '.')
ff->ff_attrib |= FA_HIDDEN;
if (!(sb.st_mode & m & 0222))
ff->ff_attrib |= FA_RDONLY;
strcpy(ff->ff_name, ff->ff_cur->d_name);
return 0;
}
}
static int
ff1(char *prefix, char *dir, char *pat, struct ffblk *ff, int attr)
{
char *pp, *cp, *ep, *xp, *bp;
struct stat sb;
int m;
ff->ff_pfx = strdup(__ff_cat(prefix, dir));
ff->ff_pat = 0;
ff->ff_dir = 0;
ff->ff_cur = 0;
ff->ff_name[0] = '\0';
ff->ff_sattr = attr;
cp = ep = pp = strdup(pat);
xp = 0;
bp = "";
for (; *cp; cp = ep)
{
while (*ep && *ep != '/') /* extract next component */
{
if (*ep == '?' || *ep == '*' || *ep == '[')
xp = ep; /* record presence of wildcard characters */
ep++;
}
if (*ep)
*ep++ = '\0';
if (xp) /* if we got a wildcard, abort */
break;
if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
continue;
xp = ff->ff_pfx; /* append component to prefix */
ff->ff_pfx = strdup(__ff_cat(xp, cp));
j_free(xp);
xp = 0;
bp = cp;
}
if (!xp) /* no wildcards; just return it */
{
strcpy(ff->ff_name, bp);
if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
stat(ff->ff_pfx, &sb) == -1 ||
(!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
(!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
!(attr & FA_HIDDEN)))
{
j_free(pp);
j_free(ff->ff_pfx);
return -1;
}
/* unreadable files are system files */
/* don't check for root: if you run nos as root you're dead anyway */
if (geteuid() == sb.st_uid)
m = 0700;
else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
m = 0070;
else
m = 0007;
if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
{
j_free(ff->ff_pfx);
j_free(pp);
return -1;
}
ff->ff_ftime = *localtime(&sb.st_mtime);
ff->ff_fsize = sb.st_size;
if (S_ISDIR(sb.st_mode))
ff->ff_attrib = FA_DIREC;
else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
else
ff->ff_attrib = FA_NORMAL;
if (*bp == '.')
ff->ff_attrib |= FA_HIDDEN;
if (!(sb.st_mode & m & 0222))
ff->ff_attrib |= FA_RDONLY;
j_free(pp);
j_free(ff->ff_pfx);
ff->ff_pfx = 0;
return 0;
}
if (*ep) /* no subdirs this version */
{
j_free(ff->ff_pfx);
j_free(pp);
return -1;
}
ff->ff_pat = strdup(cp); /* the wildcarded component */
j_free(pp);
if (!(ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")))
{
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
return -1;
}
return findnext(ff);
}
int
findfirst(char *pat, struct ffblk *ff, int attr)
{
return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
ff, attr);
}
void
findlast(struct ffblk *ff)
{
closedir(ff->ff_dir);
j_free(ff->ff_pat);
j_free(ff->ff_pfx);
}